# 属性访问发射器
# 处理 IRAttribute 节点，包括实例属性、静态属性、模块属性等

from ...ir import IRNode
from ...ir.expressions import IRAttribute, IRName
from ..core.emitter import EmitResult, NodeTypeEmitter
from ..core.context import CodeGenContext
from ..configs.operators import get_operator_precedence
from ...symbol_table import SymbolKind
from ..core.generator import get_global_generator


class AttributeEmitter(NodeTypeEmitter):
    """属性访问发射器

    处理各种属性访问：
    - 实例属性：self.x -> this->x
    - 静态属性：Class.attr -> Class::attr
    - 模块属性：module.func -> namespace::func
    - 枚举访问：Type.MEMBER -> Type::MEMBER
    """

    def __init__(self):
        super().__init__([IRAttribute])

    def emit(self, node: IRAttribute, context: CodeGenContext) -> EmitResult:
        """生成属性访问代码"""

        generator = get_global_generator()
        attr_precedence = get_operator_precedence("attr")

        # 生成基础表达式
        base_code = generator.generate_expression(
            node.value, context, parent_precedence=attr_precedence
        )

        # this.x -> this->x
        if base_code in ("self", "this"):
            return EmitResult(code=f"this->{node.attr}", precedence=attr_precedence)

        # Enum access: Type.MEMBER -> Type::MEMBER
        if node.attr.isupper():
            return EmitResult(
                code=f"{base_code}::{node.attr}", precedence=attr_precedence
            )

        # Class static member access: ClassName.member -> ClassName::member
        # 检查是否为静态成员访问
        if isinstance(node.value, IRName):
            # 检查属性是否为静态成员
            if self._is_static_member(node.value.id, node.attr, node):
                return EmitResult(
                    code=f"{base_code}::{node.attr}", precedence=attr_precedence
                )
            elif self._is_module_with_namespace(node.value.id, context):
                namespace = self._get_module_namespace(node.value.id, context)
                if namespace:
                    return EmitResult(
                        code=f"{namespace}::{node.attr}", precedence=attr_precedence
                    )

        # 默认实例属性访问
        return EmitResult(code=f"{base_code}.{node.attr}", precedence=attr_precedence)

    def _is_static_member(
        self, class_name: str, attr_name: str, current_node: IRNode
    ) -> bool:
        """检查属性是否为静态成员

        Args:
            class_name: 类名
            attr_name: 属性名
            current_node: 当前表达式节点，用于作用域查找

        Returns:
            bool: 是否为静态成员
        """
        # 使用符号表查找类符号，从当前节点开始逐层向上查找
        class_symbol = current_node.lookup_symbol(class_name)
        if not class_symbol or class_symbol.kind != SymbolKind.CLASS:
            return False

        # 获取类的IR节点
        class_node = class_symbol.ir_node
        if not class_node:
            return False

        member_node = class_node.find_symbol_ir_node(attr_name)
        if member_node and hasattr(member_node, "is_static"):
            return getattr(member_node, "is_static", False)

        return False

    def _is_module_with_namespace(
        self, module_name: str, context: CodeGenContext
    ) -> bool:
        """检查模块是否定义了命名空间"""
        ir_module = context.ir_module
        if not ir_module:
            return False

        imported_namespaces = ir_module.get_extension_param(
            "imported_module_namespaces"
        )
        if imported_namespaces:
            return module_name in imported_namespaces

        return False

    def _get_module_namespace(self, module_name: str, context: CodeGenContext) -> str:
        """获取模块的命名空间"""
        ir_module = context.ir_module
        if not ir_module:
            return ""

        # 使用命名空间映射（由 import_node 在解析时设置）
        imported_namespaces = ir_module.get_extension_param(
            "imported_module_namespaces"
        )
        if imported_namespaces:
            return imported_namespaces.get(module_name, "")

        return ""

    def get_priority(self) -> int:
        """属性发射器的优先级"""
        return 50  # 中等优先级
